package org.bintrotter;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.bintrotter.afiles.Files;
import org.bintrotter.apeer.Peer;
import org.bintrotter.metafile.Metafile;
import org.bintrotter.stats.Stats;
import org.bintrotter.tracker.StartRequest;

public class TransferContext {

	private Metafile metaFile;
	private Files files;
	private List<Peer> runningPeers;
	private Stats stats;
	private Selector selector;
	
	public TransferContext(String torrentFile, String outputDir) throws Throwable {
		
		metaFile = new Metafile(torrentFile);
		files = new Files(metaFile, outputDir);
		runningPeers = new LinkedList<Peer>();
		stats = new Stats();
		selector = Selector.open();
		
		StartRequest sr = new StartRequest(files, 30);
		
		List<org.bintrotter.tracker.Response.Peer> peers = sr.peers;
		
		Main.log.info("got + "  + peers.size() + " peers");
		
		for( Iterator<org.bintrotter.tracker.Response.Peer> it = peers.iterator(); it.hasNext(); ) {
		
			org.bintrotter.tracker.Response.Peer sad = it.next();
			
			Peer p = new Peer(sad.socktAddress() , files, stats, selector);
			
		//	p.channel().register(selector, SelectionKey.OP_CONNECT, p);
			
			runningPeers.add(p);
			
			break; // ONLY ADD ONE PEER
		}
	}
	
	public void update() throws InterruptedException {
		
		
		try {
				if(selector.select(1000) > 0)
				{
					Main.log.info("SELECT  > 0");
					Set<SelectionKey> keys = selector.selectedKeys();
					for(Iterator<SelectionKey> it = keys.iterator(); it.hasNext(); ) {
						((Peer)(it.next().attachment())).update();
					}
					
					keys.clear();
					
				} else {
					
					Main.log.info("SELECT == 0");
					for(Iterator<Peer> it = runningPeers.iterator(); it.hasNext(); )
						if(it.next().update() == Peer.State.DEAD)
							it.remove();
				}
				
				//Thread.sleep(100);
			
		} catch (IOException e) {

		}
		
		
	}
	
	public Stats.Report getStatsReport() {
		
		return stats.newReport();
	}
}
